using System;

using OpenTK.Graphics.ES20;

namespace Storyteller.Framework.Graphics
{
	public class RenderTexture : Texture
	{
		public RenderTexture(int width, int height)
			: base()
		{
			GL.GetInteger(All.FramebufferBinding, ref fbo);
			GL.BindFramebuffer(All.Framebuffer, fbo);
			
			Width = width;
			Height = height;
			
			GL.GenFramebuffers(1, ref frameBufferObject);
			GL.GenTextures(1, ref textureId);
			
			GL.BindTexture(All.Texture2D, textureId);
			GL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.Linear);
			GL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Linear);
			GL.TexParameter(All.Texture2D, All.TextureWrapS, (int)All.ClampToEdge);
			GL.TexParameter(All.Texture2D, All.TextureWrapT, (int)All.ClampToEdge);
			GL.TexImage2D(All.Texture2D, 0, (int)All.Rgba, width, height, 0, All.Rgba, All.UnsignedByte, (IntPtr)null);

			GL.BindFramebuffer(All.Framebuffer, frameBufferObject);
			GL.FramebufferTexture2D(All.Framebuffer, All.ColorAttachment0, All.Texture2D, textureId, 0);
			GL.BindFramebuffer(All.Framebuffer, fbo);
			
			All status = GL.CheckFramebufferStatus(All.Framebuffer);

			if(status != All.FramebufferComplete)
			{
				throw new InvalidOperationException("Failed to create RenderTexture");
			}
		}
		
		public void Bind()
		{
			GL.BindFramebuffer(All.Framebuffer, frameBufferObject);
			
			GL.GetInteger(All.Viewport, viewport);
			GL.Viewport(0, 0, Width, Height);
			
			GL.ClearColor(1, 0, 1, 1);
			GL.Clear((int)All.ColorBufferBit);
		}
		
		public void Unbind()
		{
			GL.BindFramebuffer(All.Framebuffer, fbo);
			
			GL.Viewport(viewport[0], viewport[1], viewport[2], viewport[3]);
		}

		protected override void Dispose(bool disposing)
		{
			if (!disposed)
			{
				if (disposing)
				{
					// dispose of managed resources
				}

				// dispose of unmanaged resources
				GL.DeleteFramebuffers(1, ref frameBufferObject);

				disposed = true;
			}

			base.Dispose(disposing);
		}

		bool disposed = false;

		int fbo = 0;
		uint frameBufferObject;
		int[] viewport = new int[4];
	}
}
